﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Web.Mvc;
using System.Xml.Linq;
using MvcForum.Net.Business;
using MvcForum.Net.Business.Utils;
using MvcForum.Net.Configuration;
using MvcForum.Net.Enums;

using MvcForum.Net.Mvc;
using MvcForum.Net.Utils;
using Nasa8x.Mvc.Helpers.Attributes;

namespace MvcForum.Net.Controllers
{
    public class ForumController : BaseController
    {
        //
        // GET: /Forum/


        public ActionResult HomePage()
        {
            return View();
        }


        public ActionResult Logout()
        {

            ForumContext.SignOut();

            return Redirect("/");

        }

        #region LostPwd

        [IsNotModified]
        public ActionResult LostPwd()
        {

            var _page = new PageEntity { Name = ForumContext.GetText("LOSTPWD", "PAGE_NAME") };

            ViewData["Page"] = _page;
            return View();

        }



        //[CaptchaValidator]
        [HttpPost]
        [IsPostbackFromThisSite]
        public ActionResult LostPwd(FormCollection form)
        {

            bool _valid = true;
            string _msg = "";
            string email = form["email"];

            string _returnUrl = "";

            if (!Nasa8x.Core.Utils.IsEmail(email))
            {
                _msg = ForumContext.GetMessage(Messages.EmailInvalid);
                _valid = false;
            }
            else if (!UsersRepository.EmailExists(email))
            {
                _msg = string.Format(ForumContext.GetText("LOSTPWD", "EMAIL_NOT_EXISTS"), email);
                _valid = false;
            }

            if (_valid)
            {
                string _subject = ForumContext.GetText("LOSTPWD", "REQUEST_SUBJECT");

                string _activeCode = Guid.NewGuid().ToString();

                UsersRepository.UpdateActiveCode(email, _activeCode);

                string _resetLink = ForumContext.GetAbsoluteUrl(ForumUrls.RESET_PWD) + "?email=" + email + "&a=" + _activeCode;

                string _message = string.Format(ForumContext.GetText("LOSTPWD", "REQUEST_MESSAGE"), email, ForumContext.Configuration.ForumName, _resetLink);
                ForumContext.SendMail(ForumContext.Configuration.ForumEmail, email, _subject, _message);

                _returnUrl = ForumContext.GetAbsoluteUrl(ForumUrls.MESSAGE, Messages.ResetPwdSendedSuccess);

            }

            return Json(new
                            {

                                success = _valid,
                                message = _msg,
                                returnUrl = _returnUrl


                            });





        }


        #endregion

        #region RequestActive

        [IsNotModified]
        public ActionResult RequestActive()
        {

            var _page = new PageEntity { Name = ForumContext.GetText("REQUEST_ACTIVE", "PAGE_NAME") };

            ViewData["Page"] = _page;
            return View();

        }

        [HttpPost]
        [IsPostbackFromThisSite]
        public ActionResult RequestActive(FormCollection form)
        {

            bool _valid = true;
            string _msg = "";
            string email = form["email"];

            string _returnUrl = "";

            if (!Nasa8x.Core.Utils.IsEmail(email))
            {
                _msg = ForumContext.GetMessage(Messages.EmailInvalid);
                _valid = false;
            }
            else if (!UsersRepository.EmailExists(email))
            {
                _msg = ForumContext.GetMessage(Messages.EmailNotExists);
                _valid = false;
            }

            if (_valid)
            {
                string _subject = ForumContext.GetText("REQUEST_ACTIVE", "EMAIL_SUBJECT");

                string _activeCode = Guid.NewGuid().ToString();

                UsersRepository.UpdateActiveCode(email, _activeCode);

                string _activeLink = ForumContext.GetAbsoluteUrl(ForumUrls.USER_ACTIVE) + "?email=" + email + "&a=" + _activeCode;

                string _message = string.Format(ForumContext.GetText("REQUEST_ACTIVE", "EMAIL_BODY"), email, _activeLink);

                ForumContext.SendMail(ForumContext.Configuration.ForumEmail, email, _subject, _message);

                _returnUrl = ForumContext.GetAbsoluteUrl(ForumUrls.MESSAGE, Messages.RequestActiveSuccess);



            }

            return Json(new
            {

                success = _valid,
                message = _msg,
                returnUrl = _returnUrl


            });

        }

        #endregion


        public ActionResult Message(string id)
        {
            var _page = new PageEntity { Name = ForumContext.GetGlobalText("ERROR_MESSAGE") };
            //_page.Url = ForumContext.GetAbsoluteUrl(ForumUrls.DEFAULT);

            ViewData["Page"] = _page;

            TempData["Message"] = ForumContext.GetMessage(id);
            return View();
        }




        //[Compress(Order = 2)]
        //[Cache(Order = 3)]
        [IsNotModified]
        public ActionResult Index()
        {

            // ForumContext.SendMail("vnnnet@gmail.com","nasavietnam@gmail.com","TestMail","Hello");

            var _page = new PageEntity
            {
                Name = ForumContext.Configuration.ForumName,
                Url = ForumContext.GetAbsoluteUrl(ForumUrls.DEFAULT)
            };

            ViewData["ForumId"] = 0;
            ViewData["Forum"] = ForumsRepository.List(0, 10, true);

            ForumContext.UserActivityUpdate(_page, 0, 0);

            ViewData["Statisc"] = ForumsRepository.Statics(ForumConfiguration.Instance.PastMinutes);
            ViewData["TimeMaxUsersOnline"] = ForumsRepository.TimeMaxUsersOnline();

            ViewData["UsersOnline"] = UsersRepository.UserOnlineList(ForumConfiguration.Instance.PastMinutes);

            return View();
        }


        //[HtmlOptimize]

        public ActionResult LogIn()
        {


            if (Request.IsAuthenticated)
            {
                return Redirect(ForumContext.GetAbsoluteUrl(ForumUrls.DEFAULT));
            }


            //ForumContext.SignOut();

            var _page = new PageEntity
                            {
                                Name = ForumContext.GetGlobalText("LOGIN"),
                                Url = ForumContext.GetAbsoluteUrl(ForumUrls.LOGIN)
                            };

            ViewData["Page"] = _page;

            ForumContext.UserActivityUpdate(_page, 0, 0);


            return View();
        }



        #region Find Post
        public ActionResult FindPost(int id)
        {


            try
            {

                int _totalRows;

                var _post = TopicsRepository.FindPost(id, out _totalRows);

                if (!string.IsNullOrEmpty(_post.RemoteUrl))
                {
                    return Redirect(_post.RemoteUrl);
                }

                int _ppp = ForumContext.Configuration.PostsPerPage;

                var _pageIndex = (int)Math.Ceiling((double)(_totalRows + 1) / _ppp);

                return Redirect(ForumContext.ThreadLink(_post.ReplyTo.HasValue ? _post.ReplyTo.Value : _post.TopicId, _post.TopicName, (_pageIndex > 1) ? _pageIndex : 1) + "#" + _post.TopicId);
            }
            catch (Exception)
            {

                return Redirect(ForumContext.GetAbsoluteUrl(ForumUrls.MESSAGE, Messages.PostNotFound));
            }
        }


        #endregion



        //[RequiresAuthentication]
        public ActionResult Post()
        {

            if (ForumContext.Logined)
            {



                try
                {

                    string _sessionId = Request.QueryString["sessionId"].Replace(" ", "+");
                    string[] _params = ForumContext.Decrypt(_sessionId);

                    int _type = int.Parse(_params[0]);
                    int _id = int.Parse(_params[1]);

                    var _cmdType = (CommandType)_type;

                    PageEntity _page;

                    TopicEntity _topic = null;

                    switch (_cmdType)
                    {
                        case CommandType.NewPost:
                        case CommandType.NewPoll:
                            ViewData["ForumNavigate"] = ForumsRepository.SubToParent(_id);
                            ViewData["SessionId"] = _sessionId;

                            ViewData["PageTitle"] = ForumContext.GetText("POST", "PAGE_NAME");

                            break;
                        case CommandType.Reply:
                        case CommandType.Quote:
                        case CommandType.Edit:
                            _topic = TopicsRepository.Detail(_id);
                            ViewData["Topic"] = _topic;

                            //ForumContext.UserInfo.Command.ForumId = _topic.ForumId;
                            ViewData["ForumNavigate"] = ForumsRepository.SubToParent(_topic.ForumId);
                            ViewData["SessionId"] = ForumContext.Encrypt(_type, _topic.ForumId, _id);

                            string _pageName = _cmdType == CommandType.Edit
                                                   ? ForumContext.GetText("POST", "EDIT_POST")
                                                   : ForumContext.GetText("POST", "REPLY_TO_TOPIC");

                           // _page = new PageEntity {Name = _pageName+ _topic.TopicName};

                            ViewData["PageTitle"] = _pageName + _topic.TopicName;
                            
                            break;


                    }

                    ViewData["Smiles"] = ForumsRepository.SmileList();
                    ViewData["CommandType"] = _cmdType;

                    string _ajax = Request.QueryString["ajax"];

                    if (!string.IsNullOrEmpty(_ajax) && (_ajax == "1" || _ajax.ToLower() == "true"))
                    {
                        return PartialView("PostView");
                    }
                    else
                    {
                        return View();
                    }


                }
                catch (Exception)
                {

                    return Redirect(ForumContext.GetAbsoluteUrl(ForumUrls.MESSAGE, Messages.UrlNotFound));

                }


            }



            var _errorPage = new PageEntity { Name = ForumContext.GetGlobalText("ERROR_MESSAGE") };

            ViewData["Page"] = _errorPage;
            ViewData["ShowLogin"] = true;
            TempData["Message"] = ForumContext.GetMessage(Messages.LoginRequired);
            return View("Message");

            // return Redirect(ForumContext.GetAbsoluteUrl(ForumUrls.DEFAULT));


        }






        [HttpPost, IsPostbackFromThisSite]
        [ValidateInput(false)]
        //[ValidateAntiForgeryToken(Salt = "POST")]
        public ActionResult AddPost(FormCollection form)
        {
            bool _susscess = false;
            string _msg = "";
            int Id = 0;


            if (ForumContext.Logined)
            {

                string[] _params = ForumContext.Decrypt(form["cmd"]);
                var _commandType = (CommandType)int.Parse(_params[0]);


                int forumId = int.Parse(_params[1]);
                int? topicId = null;
                int? replyTo = null;
                if (_commandType != CommandType.NewPost && _commandType != CommandType.NewPoll)
                    replyTo = topicId = int.Parse(_params[2]); //(ForumContext.UserInfo.Command.TopicId;

                string icon = "";
                bool _autoParseLinks = false;

                ForumContext.MapBoolean(form["autoparselinks"],out _autoParseLinks);

               // bool.TryParse(form["autoparselinks"], out _autoParseLinks);



                var forum = ForumsRepository.ForumDetail(forumId);


                string _topicName = Nasa8x.Core.Utils.ClearHtmlTags(form["subject"]);

                string _remoteUrl = form["remoteUrl"];

                string _message = form["message"];

                _message = _message.HtmlSanitize();

                //if (_autoParseLinks)
                //{
                   // _message = _message.AutoParseLink();
                //}

                int priority;
                DateTime? priorityDate = null;


                int.TryParse(form["priority"], out priority);

                if (priority == (int)PriorityType.Sticky)
                {
                    priorityDate = DateTime.Parse(form["priorityDate"]);
                }

                bool isAprroved = true;

                var moderateType = (ModerateType)forum.ModerateType;

                if (!ForumContext.UserInfo.IsAdmin && moderateType != ModerateType.None)
                {

                    isAprroved = ForumContext.UserInfo.Permissions.AlwaysPostAprroved ||
                                 (moderateType == ModerateType.AllNewRepliesButNotTopics &&
                                  _commandType == CommandType.Reply) ||
                                 (moderateType == ModerateType.AllNewTopicsButNotReplies &&
                                  (_commandType == CommandType.NewPost ||
                                   _commandType == CommandType.NewPoll));


                }


                string editedBy = string.Empty;


                switch (_commandType)
                {
                    case CommandType.NewPost:
                    case CommandType.NewPoll:
                        TopicsRepository.Add(null, _topicName, forumId, null, icon, _message, replyTo, priority,
                                             priorityDate, isAprroved, editedBy, _remoteUrl, ForumContext.UserInfo.UserName,
                                             ForumContext.UserInfo.UserId, ForumContext.ClientIp, out Id);

                        ForumsRepository.UpdateLastPost(forum.ParentId, 1, 0, ForumContext.UserInfo.UserName, Id, _topicName);

                        
                        _message += Environment.NewLine + ForumContext.GetAbsoluteUrl(ForumUrls.FIND_POST, Id);

                        if(ForumContext.Configuration.SendMailToAdminWhenNewPost)
                        {
                            ForumContext.SendMail(ForumContext.Configuration.SmtpFrom, ForumContext.Configuration.ForumEmail, _topicName, _message);    
                        }

                        break;
                    case CommandType.Reply:
                    case CommandType.Quote:
                        var topic = TopicsRepository.Detail(topicId.Value);
                        var _replyId = topic.ReplyTo.HasValue && topic.ReplyTo.Value > 0 ? topic.ReplyTo : topic.TopicId;
                        TopicsRepository.Add(null, _topicName, forumId, null, icon, _message, _replyId,
                                             priority, priorityDate, isAprroved, null, null, ForumContext.UserInfo.UserName,
                                             ForumContext.UserInfo.UserId, ForumContext.ClientIp, out Id);

                        _topicName = ForumContext.GetGlobalText("RE") + _topicName;

                        ForumsRepository.UpdateLastPost(forum.ParentId, 0, 1, ForumContext.UserInfo.UserName, Id,  _topicName);

                        _message += Environment.NewLine + Environment.NewLine + ForumContext.GetAbsoluteUrl(ForumUrls.FIND_POST, Id);

                        if (ForumContext.Configuration.SendMailToAdminWhenNewPost)
                        {
                            ForumContext.SendMail(ForumContext.Configuration.SmtpFrom, ForumContext.Configuration.ForumEmail, _topicName, _message);
                        }

                        break;

                    case CommandType.Edit:
                        TopicsRepository.Add(topicId, _topicName, forumId, null, icon, _message, null,
                                             priority, priorityDate, isAprroved, null, null, ForumContext.UserInfo.UserName,
                                             ForumContext.UserInfo.UserId, ForumContext.ClientIp, out Id);

                        break;


                }

                _susscess = true;
            }




            return Json(new
                        {
                            success = _susscess,
                            message = _msg,
                            alert = _susscess ? false : true,
                            returnUrl = _susscess ? ForumContext.GetAbsoluteUrl(ForumUrls.FIND_POST, Id) : ForumContext.GetAbsoluteUrl(ForumUrls.LOGIN)
                        });



        }



        //
        //[HtmlOptimize]
        [IsNotModified]
        public ActionResult Register()
        {
            //ForumContext.UserActivityUpdate("Đăng ký thành viên", 0, 0);

            var _page = new PageEntity
                            {
                                Name = ForumContext.GetText("REGISTER", "PAGE_NAME"),
                                Url = ForumContext.GetAbsoluteUrl(ForumUrls.REGISTER)
                            };


            ViewData["Page"] = _page;


            ForumContext.UserActivityUpdate(_page, 0, 0);


            return View();
        }

        //[HtmlOptimize]
        [IsNotModified]
        public ActionResult Members()
        {


            var _page = new PageEntity
                            {
                                Name = ForumContext.GetGlobalText("MEMBERS"),
                                Url = ForumContext.GetAbsoluteUrl(ForumUrls.MEMBERS)
                            };

            ViewData["Page"] = _page;
            ForumContext.UserActivityUpdate(_page, 0, 0);

            int _totalRows;
            var _pageIndex = ForumContext.PageIndex;
            ViewData["Users"] = UsersRepository.UsersList(_pageIndex, ForumContext.Configuration.PageSize, out _totalRows);

            ViewData["PageIndex"] = _pageIndex;
            ViewData["TotalRows"] = _totalRows;


            return View();
        }


        [IsNotModified]
        public ActionResult WhoIsOnline()
        {


            var _page = new PageEntity
                            {
                                Name = ForumContext.GetGlobalText("WHO_IS_ONLINE"),
                                Url = ForumContext.GetAbsoluteUrl(ForumUrls.WHO_IS_ONLINE)
                            };

            ViewData["Page"] = _page;


            ForumContext.UserActivityUpdate(_page, 0, 0);


            int totalRows;

            var _pageIndex = ForumContext.PageIndex;

            ViewData["UserActions"] = UsersRepository.UserActionList(_pageIndex, ForumContext.Configuration.PageSize, out totalRows);

            ViewData["PageIndex"] = _pageIndex;
            ViewData["TotalRows"] = totalRows;


            return View();
        }


        #region Search

        [HttpPost]
        [ValidateAntiForgeryToken(Salt = "SEARCH")]
        public ActionResult AdvSearch(FormCollection form)
        {


            var _sqlScript = new StringBuilder();
            var _sqlWhere = new StringBuilder();

            string _kw = form["_keywords"];
            _kw = _kw == "*" ? "" : _kw.Replace("'", "''");

            _sqlScript.Append(ForumConfiguration.Instance.MaxSearchResults > 0
                           ? String.Format("SELECT TOP {0}", ForumConfiguration.Instance.MaxSearchResults)
                           : "SELECT");

            _sqlScript.AppendFormat(" T.*, F.ForumName, F.ForumId FROM {0} INNER JOIN {1} ", "MF_Topics T", "MF_Forums F");
            _sqlScript.Append("ON T.ForumId=F.ForumId WHERE T.IsDeleted=0 AND");

            //Check Search Within
            int _temp = int.Parse(form["_searchwithin"]);

            switch (_temp)
            {
                case 0:
                    _sqlWhere.AppendFormat(" (T.TopicName LIKE N'%{0}%'  OR  T.[Message] LIKE N'%{0}%')", _kw);
                    break;
                case 1:
                    _sqlWhere.AppendFormat(" (T.TopicName LIKE N'%{0}%')", _kw);

                    break;
                default:
                    _sqlWhere.AppendFormat(" (T.[Message] LIKE N'%{0}%')", _kw);
                    break;
            }


            //-----------Search Post With UserName
            if (!string.IsNullOrEmpty(form["_UserName"]))
            {
                _sqlWhere.Append(" AND T.UserName ");
                _temp = int.Parse(form["_SearchKeywordType"]);
                string _u = form["_UserName"];
                _u = _u.Replace("'", "''");

                switch (_temp)
                {
                    case 0:
                        _sqlWhere.AppendFormat("LIKE N'%{0}%'", _u);
                        break;
                    case 1:
                        _sqlWhere.AppendFormat("LIKE N'{0}%'", _u);
                        break;
                    case 2:
                        _sqlWhere.AppendFormat("LIKE N'%{0}'", _u);
                        break;
                    default:
                        _sqlWhere.AppendFormat("='{0}'", _u);
                        break;

                }


            }

            //---------------------------

            _temp = int.Parse(form["_Replies"]);
            if (_temp > 0)
            {
                _sqlWhere.Append(" AND T.TotalReplies");

                _temp = int.Parse(form["_SearchPostsWith"]);
                _sqlWhere.AppendFormat(_temp == 0 ? ">={0}" : "<={0}", _temp);
            }

            //--------------------------

            _temp = int.Parse(form["_FindPostsFrom"]);

            if (_temp > 0)
            {

                _sqlWhere.Append(" AND T.Created");

                _sqlWhere.Append(_temp == 0 ? ">=" : "<=");

                _sqlWhere.AppendFormat("'{0}'", (DateTime.UtcNow - TimeSpan.FromDays(_temp)));

            }

            //------------------------


            if (form["_Forums"] != "0")
            {

                _sqlWhere.AppendFormat(" AND T.ForumID IN ({0})", form["_Forums"]);

            }


            //Search Retult Type 
            //0: Topics
            //1: Posts
            _temp = int.Parse(form["_ShowResultsAs"]);

            if (_temp == 0)
            {
                var _sb = new StringBuilder(500);

                _sb.Append(" T.ReplyTo IS NULL AND T.TopicId IN");
                _sb.Append("(");

                _sb.Append("SELECT DISTINCT ISNULL(T.ReplyTo,T.TopicId) FROM ");
                _sb.Append("MF_Topics T");
                _sb.Append(" WHERE ");
                _sb.Append(_sqlWhere);
                _sb.Append(")");
                _sqlScript.Append(_sb);

            }
            else
            {
                _sqlScript.Append(_sqlWhere);
            }


            //Sort Order 

            _sqlScript.Append(" ORDER BY ");

            _temp = int.Parse(form["_SortBy"]);

            switch (_temp)
            {
                case 1:
                    _sqlScript.Append("T.LastPosted");
                    break;
                case 2:
                    _sqlScript.Append("T.Created");
                    break;

                case 3:
                    _sqlScript.Append("T.Subject");
                    break;

                case 4:
                    _sqlScript.Append("T.TotalReplies");
                    break;

                case 5:
                    _sqlScript.Append("T.TotalViews");
                    break;
                default:
                    _sqlScript.Append("T.LastEdited");
                    break;

            }
            _sqlScript.Append(" " + form["_SortOrder"]);


            //return Json(new
            //          {

            //              success = false,
            //              message = _sqlScript.ToString(),

            //          });


            try
            {
                List<TopicEntity> _data = null;

                _data = TopicsRepository.AdvandedSearch(_sqlScript.ToString());

                if (_data.Count > 0)
                {
                    string _cacheKey = string.Format("MF_SEARCH-{0}", ForumContext.SessionID);

                    CacheWaper.Add(_cacheKey, _data, ForumConfiguration.Instance.SearchResultInCache);
                    string _redirect = ForumContext.GetAbsoluteUrl(ForumUrls.SEARCH) + String.Format("?do=result&Id={0}&hightlight={1}", ForumContext.SessionID, Server.UrlEncode(_kw));

                    return Redirect(_redirect);


                }

            }
            catch (Exception)
            {


            }

            return Json(new
            {

                success = false,
                message = ForumContext.GetMessage(Messages.SearchNoResults),

            });



        }

        //        [Compress]
        public ActionResult Search()
        {


            var _page = new PageEntity
                            {
                                Name = ForumContext.GetGlobalText("SEARCH"),
                                Url = ForumContext.GetAbsoluteUrl(ForumUrls.SEARCH)
                            };

            ViewData["Page"] = _page;

            ForumContext.UserActivityUpdate(_page, 0, 0);

            string _cmd = Request.QueryString["do"];

            string _cacheKey;

            switch (_cmd)
            {

                case "result":

                    _cacheKey = string.Format("MF_SEARCH-{0}", Request.QueryString["Id"]);

                    ViewData["Results"] = CacheWaper.Get(_cacheKey) as List<TopicEntity>;


                    break;
                case "quick":

                    var forumId = int.Parse(Request.QueryString["Id"]);
                    string _keyword = Server.UrlDecode(Request.QueryString["kw"]);
                    List<TopicEntity> _data = TopicsRepository.QuickSearch(forumId, _keyword, 0, ForumContext.Configuration.MaxSearchResults);

                    _cacheKey = string.Format("MF_SEARCH-{0}", ForumContext.SessionID);

                    CacheWaper.Add(_cacheKey, _data, ForumConfiguration.Instance.SearchResultInCache);
                    string _redirect = ForumContext.GetAbsoluteUrl(ForumUrls.SEARCH) + String.Format("?do=result&Id={0}&hightlight={1}", ForumContext.SessionID, Server.UrlEncode(_keyword));

                    Response.Redirect(_redirect, true);

                    break;

            }

            // return   PartialView("SearchResult");


            return View();
        }


        #endregion

        //[Compress]
        [IsNotModified]
        public ActionResult AgreeRules()
        {

            ViewData["TimeZoneList"] = ForumsRepository.TimeZoneList();

            return PartialView("RegisterForm");

        }

        //[HtmlOptimize(Order = 1)]
        //[Cache(Order = 3)]
        //[Compress]
        [IsNotModified]
        public ActionResult Forum(int id, string title, int? page)
        {

            PageEntity _errorPage;

            if (!ForumContext.Logined && !ForumContext.Configuration.AllowGuestReadForums)
            {
                _errorPage = new PageEntity { Name = ForumContext.GetGlobalText("ERROR_MESSAGE") };

                ViewData["Page"] = _errorPage;
                ViewData["ShowLogin"] = true;
                TempData["Message"] = ForumContext.GetMessage(Messages.AccessDenied);
                return View("Message");
                // return RedirectToRoute("Message", Messages.AccessDenied);


            }



            ViewData["ForumId"] = id;

            var _forum = ForumsRepository.ForumDetail(id);

            if (_forum == null)
            {

                _errorPage = new PageEntity { Name = ForumContext.GetGlobalText("ERROR_MESSAGE") };
                ViewData["Page"] = _errorPage;

                TempData["Message"] = ForumContext.GetMessage(Messages.PostNotFound);

                return View("Message");

                //return RedirectToRoute("Message", Messages.PostNotFound);

            }


            var _pageIndex = page.HasValue ? page.Value : 1;

            int _totalRows = 0;

            ViewData["ForumDetail"] = _forum;

            ViewData["ForumNavigate"] = ForumsRepository.SubToParent(id);

            ViewData["Forum"] = ForumsRepository.List(0, 3, true);



            ViewData["Topics"] = TopicsRepository.List(id, ForumContext.Logined ? ForumContext.UserInfo.IsModerator : false, _pageIndex, ForumContext.Configuration.TopicsPerPage, out _totalRows);


            ViewData["TotalRows"] = _totalRows;

            ViewData["PageIndex"] = _pageIndex;


            var _page = new PageEntity
                            {
                                Name = _forum.ForumName,
                                Url = ForumContext.ForumLink(_forum.ForumId, _forum.ForumName, _pageIndex)
                            };

            ForumContext.UserActivityUpdate(_page, id, 0);


            return View();
        }




        [IsNotModified]
        public ActionResult Thread(int id, int? page, string title)
        {

            PageEntity _errorPage;

            if (!ForumContext.Logined && !ForumContext.Configuration.AllowGuestReadTopics)
            {

                _errorPage = new PageEntity { Name = ForumContext.GetGlobalText("ERROR_MESSAGE") };
                ViewData["Page"] = _errorPage;
                ViewData["ShowLogin"] = true;
                TempData["Message"] = ForumContext.GetMessage(Messages.AccessDenied);

                return View("Message");

                //return RedirectToRoute("Message", Messages.AccessDenied);


            }



            int _pageIndex = page.HasValue ? page.Value : 1;

            var _topic = TopicsRepository.Detail(id);

            if (_topic == null)
            {

                _errorPage = new PageEntity { Name = ForumContext.GetGlobalText("ERROR_MESSAGE") };
                ViewData["Page"] = _errorPage;
                ViewData["Message"] = ForumContext.GetMessage(Messages.PostNotFound);
                return View("Message");
                //return RedirectToRoute("Message", Messages.PostNotFound);

            }

             string _description = _topic.Message.HtmlToPlainText();

            _description = !string.IsNullOrEmpty(_description) ? _description.TruncateAtWord(145) : _topic.TopicName;

            _topic.Description = _description;

            ViewData["Topic"] = _topic;

            ViewData["ForumNavigate"] = ForumsRepository.SubToParent(_topic.ForumId);


            int _totalRows;
            int _pageSize = ForumContext.Configuration.PostsPerPage;

            bool _isMod = ForumContext.Logined &&
                          (ForumContext.UserInfo.IsAdmin || ForumContext.UserInfo.IsModerated(_topic.ForumId));

            ViewData["ThreadList"] = TopicsRepository.Thread(id, _pageIndex, _pageSize, _isMod, out _totalRows);

            ViewData["Thanks"] = TopicsRepository.Thanks(id, _pageIndex, _pageSize);

            ViewData["TotalRows"] = _totalRows;

            ViewData["PageIndex"] = _pageIndex;

           
            var _page = new PageEntity
                            {
                                Name = _topic.TopicName,
                                
                Url = ForumContext.ThreadLink(_topic.TopicId, _topic.TopicName, _pageIndex)
            };

            ForumContext.UserActivityUpdate(_page, _topic.ForumId, _topic.TopicId);


            return View();
        }



        public ActionResult Refresh(string title)
        {
            if (ForumContext.Logined)
            {

            }

            return Json(new object());

        }


        [HttpPost]
        [IsPostbackFromThisSite]
        public ActionResult Thank()
        {

            if (ForumContext.Logined)
            {

                int id = int.Parse(Request.QueryString["id"]);
                TopicsRepository.ThankSave(id, ForumContext.UserInfo.UserId, ForumContext.UserInfo.UserName, 1);
                int _out;

                var _thread = TopicsRepository.Thread(id, 1, 1, true, out _out);

                ViewData["Thanks"] = TopicsRepository.Thanks(id, 1, 1);

                return PartialView("ThreadList", _thread);

            }
            return PartialView("LoginView");

        }


        [HttpPost]
        //[RequiresAuthentication]
        public ActionResult Command(string cmd)
        {


            bool _success = true;
            string _msg = "Redirecting...";
            string _items = null;

            if (ForumContext.Logined)
            {

                string[] _params = ForumContext.Decrypt(cmd);

                int type = int.Parse(_params[0]);
                int id = int.Parse(_params[1]);

                var _cmdType = (CommandType)type;
                var _command = new UserCommand();

                _command.Arg = _cmdType;


                switch (_cmdType)
                {

                    case CommandType.Thank:
                        TopicsRepository.ThankSave(id, ForumContext.UserInfo.UserId, ForumContext.UserInfo.UserName, 1);


                        int _out;

                        var _thread = TopicsRepository.Thread(id, 1, 1, true, out _out);

                        ViewData["Thanks"] = TopicsRepository.Thanks(id, 1, 1);

                        return PartialView("ThreadList", _thread);

                    case CommandType.LockForum:

                        if (ForumContext.UserInfo.IsAdmin)
                        {
                            var _db = new MainDB();
                            _db.Update<Forum>().Set(x => x.IsLocked == true).Where(x => x.ForumId == id).Execute();
                            _msg = "Diễn đàn đã được khóa";

                        }

                        break;

                    case CommandType.UnLockForum:
                        if (ForumContext.UserInfo.IsAdmin)
                        {
                            var _db = new MainDB();
                            _db.Update<Forum>().Set(x => x.IsLocked == false).Where(x => x.ForumId == id).Execute();
                            _msg = "Diễn đàn đã được mở khóa";

                        }
                        break;


                    case CommandType.LockTopic:
                        if (ForumContext.UserInfo.IsModerator)
                        {
                            var _db = new MainDB();
                            _db.Update<Topic>().Set(x => x.IsLocked == true).Where(x => x.TopicId == id).Execute();
                            _msg = "Chủ đề này đã được khóa";

                        }
                        break;

                    case CommandType.UnLockTopic:
                        if (ForumContext.UserInfo.IsModerator)
                        {
                            var _db = new MainDB();
                            _db.Update<Topic>().Set(x => x.IsLocked == false).Where(x => x.TopicId == id).Execute();
                            _msg = "Chủ đề này đã được mở khóa";
                        }

                        break;

                    case CommandType.Delete:
                        if (ForumContext.UserInfo.IsModerator)
                        {
                            new MainDB().TopicsDelete(id.ToString(), false).Execute();
                            //_db.Update<Topic>().Set(x => x.IsDeleted == true).Where(x => x.TopicId == id).Execute();
                            _items = id.ToString();
                            _msg = "Bài viết đã được xóa";

                        }
                        break;



                }




            }
            else
            {
                _success = false;

                _msg = "Bạn phải đăng nhập mới thực hiện được chức năng này";
            }

            //



            return Json(new
                            {

                                success = _success,
                                message = _msg,
                                alert = true,
                                items = _items

                            });

        }



        #region Moderator
        [HttpPost]
        public ActionResult Moderator(FormCollection form)
        {

            int _forumId = int.Parse(form["forumId"]);

            string _msg = null;
            bool _success = false;

            if (ForumContext.Logined && (ForumContext.UserInfo.IsAdmin || ForumContext.UserInfo.IsModerated(_forumId)))
            {

                var _commandType = (ModerateOptions)int.Parse(form["commandType"]);

                string _ids = form["ids"];


                switch (_commandType)
                {

                    case ModerateOptions.Approve:
                        new MainDB().TopicsQueueUpdate(_ids, true).Execute();

                        break;
                    case ModerateOptions.Queue:
                        new MainDB().TopicsQueueUpdate(_ids, false).Execute();
                        break;

                    case ModerateOptions.Lock:
                        new MainDB().TopicsLockUpdate(_ids, true).Execute();
                        break;

                    case ModerateOptions.UnLock:
                        new MainDB().TopicsLockUpdate(_ids, false).Execute();
                        break;

                    case ModerateOptions.Move:
                        int _moveToForumId = int.Parse(form["moveToForum"]);
                        new MainDB().TopicsMoveToForum(_ids, _moveToForumId).Execute();
                        break;

                    case ModerateOptions.UnMove:
                        new MainDB().TopicsMoveToForum(_ids, -1).Execute();
                        break;

                    case ModerateOptions.Del:

                        new MainDB().TopicsDelete(_ids, ForumContext.UserInfo.IsAdmin?true:false).Execute();
                        break;

                    //case ModerateOptions.UnDel:
                    //    new MainDB().TopicsDelete(_ids, false).Execute();
                    //    break;

                    case ModerateOptions.Pin:
                        DateTime _dateTime = DateTime.Parse(form["prioritydate"]);
                        new MainDB().TopicsPriorityUpdate(_ids, (short)PriorityType.Sticky, _dateTime).Execute();
                        break;
                    case ModerateOptions.UnPin:
                        new MainDB().TopicsPriorityUpdate(_ids, (short)PriorityType.Normal, DateTime.UtcNow.AddDays(-365)).Execute();
                        break;

                }

                _success = true;
            }
            else
            {
                _msg = ForumContext.GetMessage(Messages.AccessDenied);
            }


            return Json(new
            {

                success = _success,
                reload=true,
                message = _msg,
                //items = _items

            });

        }
        #endregion



        #region XML




        //  [OutputCache(Duration = 12 * 3600, VaryByParam = "*")]
        [IsNotModified]
        public ContentResult Sitemap()
        {

            var _dtf = new DateTimeFormatInfo();
            XNamespace ns = "http://www.sitemaps.org/schemas/sitemap/0.9";
            var _items = TopicsRepository.RssFetch(0, 999);
            var _sitemap = new XDocument(new XDeclaration("1.0", "utf-8", "yes"),
                new XElement(ns + "urlset",
                      new XAttribute("xmlns", "http://www.sitemaps.org/schemas/sitemap/0.9"),
                        new XAttribute(XNamespace.Xmlns + "geo",
                            "http://www.google.com/geo/schemas/sitemap/1.0"),
                    _items.Select(_item => new XElement("url",
                      new XElement("loc", ForumContext.GetAbsoluteUrl(ForumUrls.FIND_POST, _item.TopicId)),
                      new XElement("lastmod", _item.LastPosted.ToString("yyyy-MM-ddTHH:mm:sszzz", _dtf)),
                      new XElement("changefreq", "daily"),
                      new XElement("priority", "0.5")
                      ))

                    )
                  );
            return Content(_sitemap.ToString(), "text/xml");

            #region Temp
            //var items = TopicsRepository.RssFetch(0, 100);

            //XNamespace sm = "http://www.sitemaps.org/schemas/sitemap/0.9";
            //XNamespace geo = "http://www.google.com/geo/schemas/sitemap/1.0";

            //XDocument doc = new XDocument(
            //    new XElement(sm + "urlset",
            //        new XAttribute("xmlns", "http://www.sitemaps.org/schemas/sitemap/0.9"),
            //        new XAttribute(XNamespace.Xmlns + "geo",
            //            "http://www.google.com/geo/schemas/sitemap/1.0"),
            //        new XElement(sm + "url",
            //            new XElement(sm + "loc", "http://krimikort.ekstrabladet.dk/gearth.kmz"),
            //            new XElement(sm + "lastmod", String.Format("{0:yyyy-MM-dd}", DateTime.UtcNow)),
            //            new XElement(sm + "changefreq", "daily"),
            //            new XElement(sm + "priority", "1.0"),
            //            new XElement(geo + "geo",
            //                new XElement(geo + "format", "kmz")
            //            )
            //        )
            //        ,
            //        items.Select(item =>
            //            new XElement(sm + "url",
            //                new XElement(sm + "loc", ForumContext.ThreadLink(item.TopicId, item.TopicName, null)),
            //                new XElement(sm + "lastmod", String.Format("{0:yyyy-MM-dd}", item.LastPosted)),
            //                new XElement(sm + "changefreq", "daily"),
            //                new XElement(sm + "priority", "0.5")
            //            )
            //        )
            //    )
            //);

            //return Content(doc.ToString(), "text/xml");

            #endregion

        }
        [IsNotModified]
        public ContentResult Rss(int id, string _title)
        {

            //string domain = Request.Url.Host;

            string _link = (id == 0)
                              ? ForumContext.GetAbsoluteUrl(ForumUrls.RSS, 0, ForumContext.Configuration.ForumName)
                              : ForumContext.GetAbsoluteUrl(ForumUrls.RSS, id, _title);

            _title = id == 0 ? ForumContext.Configuration.ForumName : ForumContext.Configuration.ForumName + " - " + _title.Replace("-", " ");

            var _items = TopicsRepository.RssFetch(id, ForumContext.Configuration.RssFetchItems);


            var rss = new XDocument(new XDeclaration("1.0", "utf-8", "yes"),
              new XElement("rss",
                new XAttribute("version", "2.0"),
                  new XElement("channel",
                    new XElement("title", _title),
                    new XElement("link", _link),
                    new XElement("description", ForumContext.Configuration.Description),
                    new XElement("copyright", ForumContext.GetGlobalText("COPYRIGHT")),
                               _items.Select(item => new XElement("item",
                                                                  new XElement("title", item.TopicName),
                                                                  new XElement("description", item.Message),
                                                                  new XElement("link", ForumContext.GetAbsoluteUrl(ForumUrls.FIND_POST, item.TopicId)),
                                                                  new XElement("pubDate", ((DateTime)item.Created).ToString("R"))
                                                         ))
                      )
              )
            );
            return Content(rss.ToString(), "text/xml");
        }


        #endregion




    }
}

